package com.wh1200.mybatis.xmlless.plugin.visitor

import net.sf.jsqlparser.expression.ExpressionVisitorAdapter
import net.sf.jsqlparser.schema.Column
import net.sf.jsqlparser.statement.StatementVisitorAdapter
import net.sf.jsqlparser.statement.select.*

class ColumnReplaceVisitor(private val tables: Map<String, Class<*>>) : StatementVisitorAdapter() {

  override fun visit(select: Select) {
    val body = select.selectBody
    if (body is PlainSelect) {
      processPlainSelect(body)
    }
  }

  private fun processPlainSelect(plainSelect: PlainSelect) {
    val fromVisitor = object : FromItemVisitorAdapter() {

      override fun visit(subSelect: SubSelect) {
        val body = subSelect.selectBody
        if (body is PlainSelect) {
          processPlainSelect(body)
        }
      }

    }
    plainSelect.joins?.forEach {
      it.rightItem.accept(fromVisitor)
      it.onExpressions.forEach { expression ->
        val expressionVisitor = ReplaceExpressionVisitor(tables)
        expression.accept(expressionVisitor)
      }
    }
    val expressionVisitor = object : ExpressionVisitorAdapter() {
      override fun visit(expression: Column) {
        val expressionVisitor = ReplaceExpressionVisitor(tables)
        expression.accept(expressionVisitor)
      }
    }
    plainSelect.fromItem?.accept(fromVisitor)
    plainSelect.selectItems?.forEach {
      it.accept(object : SelectItemVisitorAdapter() {
        override fun visit(item: SelectExpressionItem) {
          val visitor = ReplaceExpressionVisitor(tables)
          item.expression.accept(visitor)
        }
      })
    }
    plainSelect.groupBy?.accept {
      it.groupByExpressionList.accept(expressionVisitor)
    }
    plainSelect.orderByElements?.forEach {
      it.expression.accept(ReplaceExpressionVisitor(tables))
    }
  }


}

